home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
AECUR102.ZIP
/
contrib
/
curses
/
src
/
alert.c
next >
Wrap
C/C++ Source or Header
|
1990-03-10
|
6KB
|
257 lines
/*----------------------------------------------------------------------
*
* alert.c
*
* copyright (c) 1987,88,89,90 J. Alan Eldridge
*
* DESCRIPTION:
*
* a Mac-like alert box for Curses!
*
* BUGS:
*
* maximum length of text supplied by caller is A_UROWS * A_UCOLS
* no checking is done for overflow in alertf
* but it has A_USLOP extra bytes just in case
* alerts truncates the text to fit
*
* maximum length of a word is A_UCOLS
* alerts doesn't check for this error
* but it could address outside the buffer
* and mess up the stack
*
*
*----------------------------------------------------------------------
*/
#include <stdarg.h>
#include "curses.h"
/* args to newwin */
#define A_ROWS 12 /* # rows in window */
#define A_COLS 60 /* # cols in window */
#define A_ORGY 7 /* window has origin at ... */
#define A_ORGX 10 /* ... row A_ORGY, col A_ORGX */
/* user text area */
#define A_UROWS 5 /* # rows in message area */
#define A_UCOLS 50 /* # cols in message area */
#define A_UORGY 2 /* message are has origin at ... */
#define A_UORGX 5 /* ... row A_UORGY, col A_UORGX */
#define A_USLOP 50 /* extra room in buffer so we don't overflow */
/* size of local buffer for alertf() */
#define A_UBUFSIZE (A_UROWS * A_UCOLS + 1 + A_USLOP)
static int attrib = VID_DEFBRIGHT; /* attribute to use for alert window */
int
alertf(
int die,
char *title,
char *prompt,
int *keys,
int sound,
char *fmt,
...)
{
va_list ap;
char buf[A_UBUFSIZE];
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
return alerts(die, title, prompt, keys, sound, buf);
}
static char *
getword(buf, lenp, nxtp)
char *buf, **nxtp;
int *lenp;
{
char *cp;
/*
skip leading whitespace
except for newlines
*/
while (*buf && isspace(*buf))
if (*buf == '\n') {
*lenp = 0;
*nxtp = buf + 1;
return buf;
} else
buf++;
/*
collect the word,
if there is one,
and set the length
*/
cp = buf;
while (*cp && !isspace(*cp))
cp++;
*lenp = cp - buf;
/*
skip trailing whitespace,
stopping for a newline
*/
while (*cp && isspace(*cp))
if (*cp == '\n')
break;
else
cp++;
*nxtp = cp;
return *lenp ? buf : 0;
}
void
alertattr(att)
int att;
{
if (iscolor())
attrib = att != -1 ? att : __DEFBRIGHT;
}
int
alerts(die, title, prompt, keys, sound, s)
int die;
char *title,
*prompt;
int *keys;
int sound;
char *s;
{
static int nl[] = { K_NL, K_ILLEGAL };
static int nl_esc[] = { K_NL, K_ESC, K_ILLEGAL };
int uy = 0, ux = 0, wlen, key;
char ubuf[A_UROWS][A_UCOLS + 1], *word;
WINDOW *awin, *asav, *newwin(), *savescr();
/* allocate space */
if (!(awin = newwin(A_ROWS, A_COLS, A_ORGY, A_ORGX)))
return ERR;
if (!(asav = savescr(A_ROWS, A_COLS, A_ORGY, A_ORGX))) {
delwin(awin);
return ERR;
}
/* set up the window */
setattr(awin, attrib);
werase(awin);
if (sound < 0)
wblinkon(awin);
box(awin, 1, 1);
if (title) {
mvwaddch(awin, 0, 2, ' ');
waddstr(awin, title);
waddch(awin, ' ');
}
wblinkoff(awin);
if (die)
prompt = "Sorry. Press any key to end program.";
else {
if (!prompt) {
prompt = "Press ENTER to continue ...";
keys = nl;
} else if (!keys)
keys = nl_esc;
}
/*
set up the user text ...
this is a word wrap routine
it follows the same rules as the
word wrap routine in the Mac Toolbox
a "word" is any sequence of characters
that aren't whitespace. a newline
causes an explicit wrap.
*/
while (word = getword(s, &wlen, &s))
if (!wlen) {
/* got a newline */
if (uy >= A_UROWS - 1)
break; /* truncate */
ubuf[uy][ux] = 0;
ux = 0;
uy++;
} else {
/* got a word */
/* does it fit? */
if (ux + wlen + (ux != 0) >= A_UCOLS) {
/* nope */
if (uy >= A_UROWS - 1)
break; /* truncate */
ubuf[uy][ux] = 0;
ux = 0;
uy++;
}
/* copy it into ubuf */
if (ux != 0)
ubuf[uy][ux++] = ' ';
while (wlen-- > 0)
ubuf[uy][ux++] = *word++;
}
ubuf[uy++][ux] = 0;
while (uy < A_UROWS)
ubuf[uy++][0] = 0;
/* put user text on window */
for (uy = 0; uy < A_UROWS; uy++)
mvwaddstr(awin, uy + A_UORGY, A_UORGX, ubuf[uy]);
mvwaddstr(awin, A_UORGY + A_UROWS + 2, A_UORGX, prompt);
/* pop up & get a key */
wrefresh(awin);
while (sound-- > 0)
beep();
if (die) {
wgetch(awin);
endwin();
exit(die);
}
while (kb_matchkey(keys, key = wgetch(awin)) == -1)
;
restscr(asav);
delwin(awin);
delwin(asav);
return key;
}
/*
set up video attributes
*/
void
init_alerts(void)
{
attrib = __DEFBRIGHT;
}